package org.jkuang.qstar.index.core;

import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.jkuang.qstar.commons.jni.CurMap;
import org.jkuang.qstar.index.cmp.IndexObject;
import org.jkuang.qstar.index.dic.TermsDic;
import org.jkuang.qstar.index.filter.QueryFilter;
import org.jkuang.qstar.index.filter.ResultFilter;
import org.jkuang.qstar.index.iterator.QueryStatus;
import org.jkuang.qstar.index.store.DataNode;
import org.jkuang.qstar.index.store.DataStruct;

/**
 * 
 * @author jkuang 2012年11月17日
 *
 */
public class IndexReader {

	private QueryExecuter executer;

	public IndexReader(ReentrantReadWriteLock rwlock, TermsDic termsDic, DataStruct<IndexObject> indexs, CurMap store) {
		this.executer = new QueryExecuter(termsDic, rwlock, indexs, store);
	}

	/**
	 * 按照单一的语法条件查询数据
	 * 
	 * @param syntax  查询语法
	 * @param _s_sort 起始时间,若起始时间，终止时间都为零，则表示不限制时间
	 * @param _e_sort 终止时间,若起始时间，终止时间都为零，则表示不限制时间
	 * @param start   起始条数
	 * @param rows    获取多少条数据
	 * @param count   最多统计达到多少条后不再进行统计
	 * @param desc    在指定范围内按照倒序还是正序取数据
	 * @param filter  结果过滤器，可用于判重或读取数据
	 * @return 返回id列表，ids[0] 表示 count的总数，ids[1-m] 表示具体的数据
	 */
	public long[] query(String syntax, long _s_sort, long _e_sort, int start, int rows, int count, boolean desc,
			QueryFilter qfilter,ResultFilter rfilter) {
		return toKeys(executer.execute(syntax, toBeginDate(_s_sort), toEndDate(_e_sort), desc,
				new QueryStatus<DataNode>(start, rows, count,qfilter, rfilter)));
	}

	/**
	 * 批量表达式做OR条件运算（每个表达式都是一个完整的可查找条件）
	 * 
	 * @param params 条件list
	 * @param start  起始条数
	 * @param rows   获取多少条数据
	 * @param count  最多统计达到多少条后不再进行统计
	 * @param desc   在指定范围内按照倒序还是正序取数据
	 * @param filter 结果过滤器，可用于判重或读取数据
	 * @return 返回id列表，ids[0] 表示 count的总数，ids[1-m] 表示具体的数据
	 */
	public long[] query(List<QueryArg> params, int start, int rows, int count, boolean desc,QueryFilter qfilter, ResultFilter filter) {
		return toKeys(executer.execute(params, desc, new QueryStatus<DataNode>(start, rows, count,qfilter, filter)));
	}

	/**
	 * 
	 * @param params 多个条件，每个条件均需要获取前N条数据
	 * @param rows   获取多少条数据
	 * @param count  最多统计达到多少条后不再进行统计
	 * @param desc   在指定范围内按照倒序还是正序取数据
	 * @return <每个条件-结果集>
	 */
	public Map<QueryArg, QueryStatus<DataNode>> query(List<QueryArg> params, int rows, int count, boolean desc) {

		return executer.execute(params, rows, count, desc);
	}

	/**
	 * 将查询结果转换为long型主键
	 * 
	 * @param status 查询结构对象
	 * @return
	 */
	private long[] toKeys(QueryStatus<DataNode> status) {
		List<DataNode> result = status.getResult();
		long[] ids = new long[result.size() + 1];
		ids[0] = status.getOffset();
		for (int i = 1; i < ids.length; i++) {
			ids[i] = result.get(i - 1).key();
		}
		return ids;
	}

	/**
	 * 
	 * @param _s_sort 将整形时间戳转换为node边界值
	 * @return datanode对象
	 */
	private static DataNode toBeginDate(long _s_sort) {
		if (_s_sort != 0) {
			return DataNode.create(Long.MIN_VALUE, _s_sort);// addToDic(Long.MIN_VALUE, _s_sort, null);
		}
		return null;
	}

	/**
	 * 
	 * @param _e_sort 将整形时间戳转换为node边界值
	 * @return datanode对象
	 */
	private static DataNode toEndDate(long _e_sort) {
		if (_e_sort != 0) {
			return DataNode.create(Long.MAX_VALUE, _e_sort);
		}
		return null;
	}

	/**
	 * 查询参数
	 * 
	 * @author jkuang 2012年11月17日
	 *
	 */
	public static class QueryArg {
		String syntax;
		DataNode _s_sort_;
		DataNode _e_sort_;

		public QueryArg(String syntax, long _s_sort, long _e_sort) {
			this.syntax = syntax;
			this._s_sort_ = toBeginDate(_s_sort);
			this._e_sort_ = toEndDate(_e_sort);
		}
	}
}
